﻿#include <iostream>

using namespace std;

//int main()
//{
//	int x = 1, y = 2;
//	int&& rx = x + y;
//	
//	cout << &(x + y);	//右值 x+y 不取地址
//	cout << &rx;	  //右值引用变量的属性是左值
//	return 0;
//}

//引⽤延⻓⽣命周期 

//int main()
//{
//	string s1 = "CSDN";
//
//	std::string&& r2 = s1 + s1; // 右值引⽤延长生存期
//	r2 = "hello CSDN";			// 能修改非 const 引用变量
//
//	const string& s3 = s1 + s1;// 左值引⽤延长生存期
//	//s3 = "Test";			   // const 左值引用不能被修改
//	return 0;
//}


//左值和右值的参数匹配 

//void func(int& x)  //非const左值引用
//{
//	cout << "int&" << endl;
//}
//
//void func(const int& x) //const左值引用
//{
//	cout << "const int&" << endl;
//}
//
//int main()
//{
//	int x = 1;
//	const int y = 2;
//
//	func(y); 
//	func(x); 
//
//	return 0;
//}


//void func(int& x)
//{
//	cout << "int&\n";
//}
//void func(const int& x)
//{
//	cout << "const int&\n";
//}
//void func(int&& x)
//{
//	cout << "int&&\n";
//}
//int main()
//{
//	int x = 1;
//	const int cx = 2;
//	func(x);		// 调用 func(int&)
//	func(cx);		// 调用 func(const int&)
//	func(3);		// 调用 func(int&&)，如果没有 func(int&&) 重载则会调用 func(const int&)
//	func(move(x));  // 调用 func(int&&)
//	return 0;
//}


//移动语义
class A
{
	friend void func(A a);
public:
	A(int x = 10)
		:_size(x)
	{
		_ptr = new int[x];
		for (int i = 0; i < x; i++)
		{
			_ptr[i] = i;
		}
	}

	A(A& a)
	{
		int* tmp = new int[a._size];		
		//delete[] _ptr;
		_ptr = tmp;
		for (int i = 0; i < a._size; i++)
		{
			_ptr[i] = a._ptr[i];
		}
		_size = a._size;
	}

	A& operator=(A& a)
	{
		int* tmp = new int[a._size];
		//delete[] _ptr;
		_ptr = tmp;
		for (int i = 0; i < a._size; i++)
		{
			_ptr[i] = a._ptr[i];
		}
		_size = a._size;
		return *this;
	}

	//A(A&& a) noexcept
	//{
	//	swap(a._ptr, _ptr);
	//	swap(_size, a._size);
	//}

	//A& operator=(A&& a) noexcept
	//{
	//	swap(a._ptr, _ptr);
	//	swap(a._size, _size);
	//	return *this;
	//}

	~A()
	{
		delete[] _ptr;
	}

private:
	int* _ptr;
	int _size;
};

void func(A a)
{
	for (int i = 0; i < a._size; i++)
	{
		cout << a._ptr[i] << " ";
	}
}


A mytest()
{
	A aa(4);

	return aa;
}

int main()
{
	A a1(6);

	//func(a1);

	//func(mytest());

	A a2 = a1;

	return 0;
}

// 引⽤折叠
//int main()
//{
//	//typedef int& lref;
//	//typedef int&& rref;
//	//
//	//int n = 2;
//	//lref& lf = n;
//
//	//cout << typeid(lf).name() << endl;
//
//	typedef int& lef;
//	typedef int&& ref;
//	int n = 0;
//	lef& r1 = n;  // r1 的类型是 int&
//	lef&& r2 = n; // r2 的类型是 int&
//	ref& r3 = n;  // r3 的类型是 int&
//	ref&& r4 = 1; // r4 的类型是 int&&
//
//
//	return 0;
//}

// 由于引⽤折叠规则，f1实例化以后总是一个左值引用
//template<class T>
//void f1(T& x)
//{
//	cout << x << endl;
//}
//
//// 由于引用折叠规则，f2实例化后可以是左值引⽤，也可以是右值引用
//template<class T>
//void f2(T&& x)
//{
//	cout << x << endl;
//}
//
//int main()
//{
//	int n = 2;
//	//无论对f1模版是否显示实例化，折叠后总是左值引用
//	f1<int&>(n);  
//	//传入右值会报错
//	//f1<int>(2);
//	//f1<int&>(0);
//	//f1<int&&>(1);
//
//	//对于f2模版传入左值和右值都可以
//	f2(2); // 10是右值，推导出T为int，模板实例化为void f2(int&& x)
//	f2(n); //n为左值，推导出T为int&，引⽤折叠，模板实例化为 void f2(int& x)
//	
//	const int b = 8;
//	f2(b); // b是左值，推导出T为const int&，引用折叠后，模板实例化为 void f2(const int& x)
//	f2(move(b));// std::move(b)右值，推导出T为const int，模板实例化为void f2(const int&& x)	
//	return 0;
//}

//完美转发

//void func(int& x) { cout << "左值引用" << endl; }
//void func(const int& x) { cout << "const 左值引用" << endl; }
//void func(int&& x) { cout << "右值引用" << endl; }
//void func(const int&& x) { cout << "const 右值引用" << endl; }
//
//template <class T>
//void function(T&& x)
//{
//	func(forward<T>(x));
//}
//
//int main()
//{
//
//
//	return 0;
//}